// ignore_for_file: constant_identifier_names, deprecated_member_use

import 'dart:io';

import 'package:dio/dio.dart';
import 'package:dio/io.dart';
import 'package:xvideos/hj_utils/http_manager.dart';
import 'package:xvideos/tools_base/debug_log.dart';
import 'package:package_info_plus/package_info_plus.dart';

import '../../config/address.dart';
import '../../config/config.dart';
import '../../hj_utils/light_model.dart';
import '../../hj_utils/text_util.dart';
import '../../hj_utils/utils.dart';
// import 'client_api.dart';
import 'http_header_interceptor.dart';
import 'http_resp_interceptor.dart';
import 'http_signature_interceptor.dart';

/// 连接超时15秒
const int CONNECT_TIME_OUT = 15 * 1000;

final netManager = NetManager();

class NetManager {
  final Dio _clientDio = Dio();
  Dio get clientDio {
    return _clientDio;
  }

  // Dio _bankDio;
  static bool _inited = false;
  static String tokenKey = '_key_net_token';
  static String uaKey = '_key_user_agent';

  init(String baseUrl) {
    httpManager.init(baseUrl);
    _createDio(
      options: BaseOptions(
        connectTimeout: const Duration(seconds: CONNECT_TIME_OUT),
        baseUrl: baseUrl,
      ),
    );
    _clientDio.interceptors.add(HttpHeaderInterceptor());
    _clientDio.interceptors.add(SignatureInterceptor());
    _clientDio.interceptors.add(HttpRespInterceptor());
    _inited = true;
    // _client = ClientApi(_clientDio);
    // bankApi = BankApi(_bankDio);
  }

  reset() {
    netManager.init(Address.baseApiPath ?? "");
  }

  static bool get isInited => _inited;

  Future<String> getToken() async {
    var token = (await lightKV.getString(tokenKey)) ?? '';
    // token = token.substring(10);
    // Address.token = token;
    print('token ==== $token');
    return token;
  }

  Future setToken(String? token) async {
    // 该key不共享，不放全局变量
    Address.token = token;
    return lightKV.setString(tokenKey, token);
  }

  /// deviceId 不为空的话，表示切换一次设备；
  Future<String> userAgent({String? deviceId}) async {
    String oldUa = (await lightKV.getString(uaKey)) ?? '';
    if (TextUtil.isEmpty(deviceId) && TextUtil.isNotEmpty(oldUa)) {
      return oldUa;
    }
    String newUa = await _genUserAgent(deviceId);
    if (TextUtil.isNotEmpty(newUa)) lightKV.setString(uaKey, newUa);
    return newUa;
  }

  /// 清除ua
  Future clearUserAgent() {
    return lightKV.setString(uaKey, null);
  }

  Future<String> _genUserAgent(String? deviceId) async {
    if (TextUtil.isEmpty(deviceId)) {
      deviceId = await getDeviceOaid();
    }

    String devType = await getDevType();
    String sysType = Platform.operatingSystem;

    String ver = Config.innerVersion;
    String buildID = await getFixedPkgName();
    String ua = Uri.encodeComponent(
        "DevID=$deviceId;DevType=$devType;SysType=$sysType;Ver=$ver;BuildID=$buildID;Mac=${Config.macAddress};GlobalDevID=${Config.imei}");
    return ua;
  }

  /// 获取修正后的pkgName
  Future<String> getFixedPkgName() async {
    PackageInfo packageInfo = await PackageInfo.fromPlatform();
    if (Platform.isIOS) {
      return Config.IOS_TF_BUNDLE_ID;
    } else {
      return packageInfo.packageName;
    }
  }

  /// 服务器时间
  DateTime? _serverTime;

  /// 服务器时间和本地时间的差值
  int _diffTimeInSeconds = 0;

  /// 获取上一次服务器返回的时间
  DateTime? getServerTime() {
    if (null != _serverTime) {
      return _serverTime;
    } else {
      return DateTime.now();
    }
  }

  /// 设置服务器时间
  void setServerTime(String? serverTimeS) {
    if (TextUtil.isNotEmpty(serverTimeS)) {
      _serverTime = DateTime.parse(serverTimeS!);
      _diffTimeInSeconds = DateTime.now().difference(_serverTime!).inSeconds;
      debugLog("============>server diff from local in seconds:$_diffTimeInSeconds");
    }
  }

  /// 获取修复后的本地时间,应该是和服务器时间是同步的
  DateTime getFixedCurTime() {
    return DateTime.now().add(Duration(seconds: -_diffTimeInSeconds));
  }

  _createDio({BaseOptions? options}) {
    final defaultOptions = BaseOptions(
      connectTimeout: const Duration(seconds: 15),
      receiveTimeout: const Duration(seconds: 15),
      // dio 原生会加上 request header:accept-encoding gzip，导致部分请求失败
      // headers: {HttpHeaders.acceptEncodingHeader: "*"},
      validateStatus: (int? status) => (status ?? 600) < 600,
    );
    options ??= defaultOptions;
    options.headers[HttpHeaders.acceptEncodingHeader] = "*";
    // var dio = Dio(options);
    _clientDio.options = options;

    var adapter = DefaultHttpClientAdapter();
    // var adapter = DefaultHttpClientAdapter();
    adapter.onHttpClientCreate = (client) {
      client.badCertificateCallback = (X509Certificate cert, String host, int port) => true;
      return client;
    };
    _clientDio.httpClientAdapter = adapter;

    // if (FlutterBase.proxyEnable &&
    //     TextUtil.isNotEmpty(FlutterBase.proxyUrl) &&
    //     dio.httpClientAdapter is DefaultHttpClientAdapter) {
    //   (dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate =
    //       (client) {
    //     client.findProxy = (uri) {
    //       return FlutterBase.proxyUrl;
    //     };
    //   };
    // }
  }
}

Dio createDio({BaseOptions? options}) {
  final defaultOptions = BaseOptions(
    connectTimeout: const Duration(seconds: 15),
    receiveTimeout: const Duration(seconds: 15),
    // dio 原生会加上 request header:accept-encoding gzip，导致部分请求失败
    // headers: {HttpHeaders.acceptEncodingHeader: "*"},
    validateStatus: (int? status) => (status ?? 600) < 600,
  );
  options ??= defaultOptions;
  options.headers[HttpHeaders.acceptEncodingHeader] = "*";
  var dio = Dio(options);

  var adapter = DefaultHttpClientAdapter();
  // var adapter = DefaultHttpClientAdapter();
  adapter.onHttpClientCreate = (client) {
    client.badCertificateCallback = (X509Certificate cert, String host, int port) => true;
    return client;
  };
  dio.httpClientAdapter = adapter;

  // if (FlutterBase.proxyEnable &&
  //     TextUtil.isNotEmpty(FlutterBase.proxyUrl) &&
  //     dio.httpClientAdapter is DefaultHttpClientAdapter) {
  //   (dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate =
  //       (client) {
  //     client.findProxy = (uri) {
  //       return FlutterBase.proxyUrl;
  //     };
  //   };
  // }
  return dio;
}
